﻿#include "scriptitemtree.h"
ScriptItemTree::ScriptItemTree(QWidget *parent) : QTreeWidget(parent)
{
    this->setWindowTitle(tr("ScriptItemTree"));
    this->setObjectName("WidgetScriptItemTreeObject");

    QStringList labels;
    labels<<tr("Name")<<tr("STime")<<tr("ETime");
    this->setColumnCount(3);
    this->setHeaderLabels(labels);
    this->setColumnWidth(0,200);

    CommonTreeDelegate* delegate = new CommonTreeDelegate(this);
    QList<int> lstInt;
    lstInt.append(0);
    delegate->setColDisable(lstInt);
    this->setItemDelegate(delegate);

    TaskManager::getInstance()->registNotify(this);
    connect(this,SIGNAL(sig_updateTask(QString , QString, QString)),TaskManager::getInstance(),SLOT(slot_updateTask(QString,QString,QString)));
    connect(this,SIGNAL(sig_selectCommand(QString)),TaskManager::getInstance(),SLOT(slot_commandSelect(QString)));
}

void ScriptItemTree::updateTask(const QString &taskObj, const QString &cmdObj, const QString &scriptObj)
{

    if(taskObj.isEmpty())
    {
        QVector<TaskItem*> vctTask = TaskManager::getInstance()->allTasks();
        foreach (TaskItem* ptask, vctTask) {
            QVector<CommandItem *> vctCommand = ptask->allCommands();
            foreach (CommandItem* pCommand, vctCommand) {
                QTreeWidgetItem* ptopItem = isExistTopItem(pCommand->objectName());
                if(NULL == ptopItem)
                {
                    QStringList lstValue;
                    lstValue.append(pCommand->getName());
                    lstValue.append(QString::number(pCommand->getValue(ScriptItem::Time_Start),'f',6));
                    lstValue.append(QString::number(pCommand->getValue(ScriptItem::Time_End),'f',6));
                    ptopItem = new QTreeWidgetItem(lstValue);
                    ptopItem->setData(0,Qt::WhatsThisRole,pCommand->objectName());

                    this->addTopLevelItem(ptopItem);
                }
            }
        }
    }
    else if(cmdObj.isEmpty())
    {
        TaskItem* pcurTask = TaskManager::getInstance()->getTask(taskObj);
        if(NULL == pcurTask)
            return;

        QVector<CommandItem *> vctCommand = pcurTask->allCommands();
        foreach (CommandItem* pCommand, vctCommand) {
            QTreeWidgetItem* ptopItem = isExistTopItem(pCommand->objectName());
            if(NULL == ptopItem)
            {
                QStringList lstValue;
                lstValue.append(pCommand->getName());
                lstValue.append(QString::number(pCommand->getValue(ScriptItem::Time_Start),'f',6));
                lstValue.append(QString::number(pCommand->getValue(ScriptItem::Time_End),'f',6));
                ptopItem = new QTreeWidgetItem(lstValue);
                ptopItem->setData(0,Qt::WhatsThisRole,pCommand->objectName());

                this->addTopLevelItem(ptopItem);
            }
            else
            {
                ptopItem->setData(0,Qt::WhatsThisRole,pCommand->objectName());
                ptopItem->setData(1,Qt::DisplayRole,QString::number(pCommand->getValue(ScriptItem::Time_Start),'f',6));
                ptopItem->setData(2,Qt::DisplayRole,QString::number(pCommand->getValue(ScriptItem::Time_End),'f',6));
            }
        }
    }
    else if(scriptObj.isEmpty())
    {
        TaskItem* pcurTask = TaskManager::getInstance()->getTask(taskObj);
        if(NULL == pcurTask)
            return;

        CommandItem* pCurCommand = pcurTask->getCommand(cmdObj);
        if(NULL == pCurCommand)
            return;
        QTreeWidgetItem* ptopItem = isExistTopItem(pCurCommand->objectName());
        if(NULL == ptopItem)
        {
            QStringList lstValue;
            lstValue.append(pCurCommand->getName());
            lstValue.append(QString::number(pCurCommand->getValue(ScriptItem::Time_Start),'f',6));
            lstValue.append(QString::number(pCurCommand->getValue(ScriptItem::Time_End),'f',6));
            ptopItem = new QTreeWidgetItem(lstValue);
            ptopItem->setData(0,Qt::WhatsThisRole,pCurCommand->objectName());

            this->addTopLevelItem(ptopItem);
        }

        foreach (ScriptItem* pScript, pCurCommand->allScripts()) {
            QTreeWidgetItem* pChildItem = getChildTreeItem(ptopItem,pScript->objectName());
            if(NULL == pChildItem)
            {
                QStringList lstValue;
                lstValue.append(pScript->getName());
                lstValue.append(QString::number(pScript->getValue(ScriptItem::Time_Start),'f',6));
                lstValue.append(QString::number(pScript->getValue(ScriptItem::Time_End),'f',6));
                pChildItem = new QTreeWidgetItem(lstValue);
                pChildItem->setData(0,Qt::WhatsThisRole,pScript->objectName());

                ptopItem->addChild(pChildItem);
            }
        }
    }
    else
    {
        TaskItem* pcurTask = TaskManager::getInstance()->getTask(taskObj);
        if(NULL == pcurTask)
            return;

        CommandItem* pCurCommand = pcurTask->getCommand(cmdObj);
        if(NULL == pCurCommand)
            return;
        QTreeWidgetItem* ptopItem = isExistTopItem(pCurCommand->objectName());
        if(NULL == ptopItem)
        {
            QStringList lstValue;
            lstValue.append(pCurCommand->getName());
            lstValue.append(QString::number(pCurCommand->getValue(ScriptItem::Time_Start),'f',6));
            lstValue.append(QString::number(pCurCommand->getValue(ScriptItem::Time_End),'f',6));
            ptopItem = new QTreeWidgetItem(lstValue);
            ptopItem->setData(0,Qt::WhatsThisRole,pCurCommand->objectName());

            this->addTopLevelItem(ptopItem);
        }

        ScriptItem* pScript = pCurCommand->getScript(scriptObj);
        if(NULL == pScript)
            return;

        QTreeWidgetItem* pChildItem = getChildTreeItem(ptopItem,pScript->objectName());
        if(NULL == pChildItem)
        {
            QStringList lstValue;
            lstValue.append(pScript->getName());
            lstValue.append(QString::number(pScript->getValue(ScriptItem::Time_Start),'f',6));
            lstValue.append(QString::number(pScript->getValue(ScriptItem::Time_End),'f',6));
            pChildItem = new QTreeWidgetItem(lstValue);
            pChildItem->setData(0,Qt::WhatsThisRole,pScript->objectName());

            ptopItem->addChild(pChildItem);
        }
    }
}

void ScriptItemTree::commandSelect(const QString &cmdObj)
{
    for(int i=0; i<this->topLevelItemCount(); ++i)
    {
        QTreeWidgetItem* pTopItem = this->topLevelItem(i);
        if(pTopItem->data(0,Qt::WhatsThisRole).toString().contains(cmdObj,Qt::CaseInsensitive))
        {
            this->setCurrentItem(pTopItem);
            break;
        }
        else
            continue;
    }
}

QTreeWidgetItem* ScriptItemTree::isExistTopItem(QString sItemText, int role)
{
    for(int i=0; i<this->topLevelItemCount(); ++i)
    {
        if(this->topLevelItem(i)->data(0,role).toString() == sItemText)
        {
            return this->topLevelItem(i);
        }
        else
        {
            continue;
        }
    }
    return NULL;
}

QTreeWidgetItem *ScriptItemTree::getChildTreeItem(QTreeWidgetItem * parent,QString sItemText, int role)
{
    for(int i=0; i<parent->childCount(); ++i)
    {
        if(parent->child(i)->data(0,role).toString() == sItemText)
        {
            return parent->child(i);
        }
        else
        {
            continue;
        }
    }
    return NULL;
}

void ScriptItemTree::mousePressEvent(QMouseEvent *e)
{
    QTreeWidgetItem * pTreeItem = itemAt(e->pos());
    if(NULL != pTreeItem)
        this->setCurrentItem(pTreeItem);

    if (e->button() == Qt::LeftButton)
    {
        // 选中某个对象，通知到另外两个显示控件
        if (NULL != pTreeItem && pTreeItem->data(0, Qt::WhatsThisRole).toString().section(":", 0, 0).contains("Command"))
        {
            emit sig_selectCommand(pTreeItem->data(0, Qt::WhatsThisRole).toString());
        }
    }
    else if (e->button() == Qt::RightButton)
    {
        QTreeWidgetItem * pTreeItem = itemAt(e->pos());
        this->setCurrentItem(pTreeItem);

        QMenu menu;
        //menu.addAction(QIcon(),tr("LoadSolution"),this,SLOT(slot_loadSolution()));
        //menu.addAction(QIcon(),tr("SaveSolution"),this,SLOT(slot_saveSolution()));
        menu.addAction(QIcon(),tr("SortCommond"),this,SLOT(slot_sortCommand()));
        menu.addAction(QIcon(),tr("AutoPlan"),this,SLOT(slot_autoPlan()));
        menu.addAction(QIcon(),tr("EditStyle"),this,SLOT(slot_editStyle()));

        if(NULL != pTreeItem)
        {
            if(pTreeItem->data(0,Qt::WhatsThisRole).toString().section(":",0,0).contains("Command",Qt::CaseInsensitive))
            {
                menu.addAction(QIcon(),tr("Forward to align"),this,SLOT(slot_ForwardToAlign()));
            }
            if(pTreeItem->data(0,Qt::WhatsThisRole).toString().section(":",0,0).contains("Command",Qt::CaseInsensitive))
            {
                menu.addAction(QIcon(),tr("5min Forward to align"),this,SLOT(slot_5ForwardToAlign()));
            }
        }
        menu.exec(QCursor::pos());
    }


    QTreeWidget::mousePressEvent(e);
}

void ScriptItemTree::slot_sortCommand()
{
    QVector<CommandItem *> vctCommand = TaskManager::getInstance()->getSortCommand();
    for(int i=0; i<vctCommand.count(); ++i)
    {
        QTreeWidgetItem* topItem  = isExistTopItem(vctCommand.at(i)->objectName());
        // 一旦触发，说明程序逻辑存在问题
        if(NULL == topItem)
        {
            qWarning()<<"tree top item has wrong";
        }
        else
        {
            this->takeTopLevelItem(this->indexOfTopLevelItem(topItem));
            this->insertTopLevelItem(i,topItem);
        }

    }

    // 程序保护，一旦触发，说明程序逻辑存在问题
    while(this->topLevelItemCount() > vctCommand.count())
    {
        qWarning()<<"tree top item has wrong";
        delete this->takeTopLevelItem(this->topLevelItemCount());
    }

}

void ScriptItemTree::slot_5ForwardToAlign()
{
    QVector<CommandItem *>vctCommands=TaskManager::getInstance()->getSortCommand();
    CommandItem *curcommand=NULL;
    CommandItem *precommand=NULL;
    for(int i=0;i<vctCommands.count();++i)
    {
        double curstarttime=0.0;
        curcommand=vctCommands.at(i);
        double curdToTime=curcommand->getValue(ScriptItem::Time_End)-curcommand->getValue(ScriptItem::Time_Start);
        if(i==0)
        {
            curcommand->setValue(ScriptItem::Time_Start,0.0);
            curcommand->setValue(ScriptItem::Time_End,curdToTime);
        }
        else
        {
            precommand=vctCommands.at(i-1);
            if((precommand->getName().contains("FastPointing")&&curcommand->getWorkMode()==CommandItem::Mode_FastPoint)/*||curcommand->getName().contains("FulldiskNormal")*/)
            {
                curstarttime=precommand->getValue(ScriptItem::Time_End);

            }
            else if(curcommand->getName().contains("FulldiskNormal"))
            {
                curstarttime=precommand->getValue(ScriptItem::Time_End)+FulldiskstableTime;
            }
            else if(curcommand->getName().contains("MidRegionScan"))
            {
                curstarttime=precommand->getValue(ScriptItem::Time_End)+MidReginstableTime;
            }
            else if(curcommand->getName().contains("ChinascanNormal"))
            {
                curstarttime=precommand->getValue(ScriptItem::Time_End)+ChinaScanstableTime;
            }
            else
            {
                curstarttime=precommand->getValue(ScriptItem::Time_End)+instructionIntervalTime;
            }

            curcommand->setValue(ScriptItem::Time_Start,curstarttime);
            curcommand->setValue(ScriptItem::Time_End,curstarttime+curdToTime);
        }
        //第一个指令开始时间为0，第二个指令开始时间为上一个指令结束时间+对应的指令间隔时间。如果第一个指令是快速指向，并且第二个指令模式是fastpoint
        //第二个指令开始时间为第一个指令结束时间。。如果第二个指令是全员盘，开始时间是0第一个指令的结束时间



    }
    TaskManager::getInstance()->slot_updateTask(QString(),QString(),QString());
}

/**
 * @brief ScriptItemTree::slot_ForwardToAlign
 *
 * 指令向前对齐
 */
void ScriptItemTree::slot_ForwardToAlign()
{


    QTreeWidgetItem* pCurItem = this->currentItem();

    QVector<CommandItem *> vctCommand = TaskManager::getInstance()->getSortCommand();//->getpCurItem
    //对齐后指令开始时间
    double newstart;
    for(int i=0; i<vctCommand.count(); ++i)
    {
        if(vctCommand.at(i)->objectName() == pCurItem->data(0,Qt::WhatsThisRole).toString() && i>0)
        {

            // 前一条指令结束时间
            double dLastCommandEndTime = vctCommand.at(i-1)->getValue(ScriptItem::Time_End);

            // 当前指令开始和结束时间
            double dCurCmdSTime = vctCommand.at(i)->getValue(ScriptItem::Time_Start);
            double dCurCmdETime = vctCommand.at(i)->getValue(ScriptItem::Time_End);
            //如果前一条指令是快速指向，就要判断当前指令是快速指向还是区域扫描。如果是快速指向，开始位置就是前一条指令结束位置
            //如果是区域扫描，开始位置就是结束位置+0.2.
            //如果不是快速指向就是0.1;
            if(vctCommand.at(i-1)->objectName().contains("FastPointing"))
            {
                if(vctCommand.at(i)->getWorkMode()==CommandItem::Mode_FastPoint)
                {
                    newstart=dLastCommandEndTime;
                }
                else
                {
                    if(vctCommand.at(i)->getName()=="FulldiskNormal")
                    {
                        newstart=dLastCommandEndTime+FulldiskstableTime;
                    }
                    else if(vctCommand.at(i)->getName()=="ChinascanNormal")
                    {
                        newstart=dLastCommandEndTime+ChinaScanstableTime;
                    }
                    else
                    {
                        newstart=dLastCommandEndTime+MidReginstableTime;

                    }
                }
            }
            else
                newstart=dLastCommandEndTime+instructionIntervalTime;
            vctCommand.at(i)->setValue(ScriptItem::Time_Start,newstart);
            vctCommand.at(i)->setValue(ScriptItem::Time_End,newstart+dCurCmdETime-dCurCmdSTime);

            pCurItem->setText(1,QString::number(vctCommand.at(i)->getValue(ScriptItem::Time_Start),'f',6));
            pCurItem->setText(2,QString::number(vctCommand.at(i)->getValue(ScriptItem::Time_End),'f',6));
            emit sig_updateTask(vctCommand.at(i)->parent()->objectName(),vctCommand.at(i)->objectName(),QString());

            break;
        }
        else
        {
            //emit sig_updateTask(vctCommand.at(i)->parent()->objectName(),vctCommand.at(i)->objectName(),QString());
            continue;
        }
    }

}

bool ScriptItemTree::autoPlansPaceScan()
{
    //将全圆盘前自动补齐指令删除，重新补充
    QVector<TaskItem *> vctTask = TaskManager::getInstance()->allTasks();

    foreach (TaskItem* pTask, vctTask) {
        QVector<CommandItem *> vctCommand = pTask->allCommands();
        foreach (CommandItem* pCommand, vctCommand) {
            if(pCommand->objectName().contains("sPaceScanAuto")/*||pCommand->objectName().contains("sPaceScanAutoPre")*/)
            {
                TaskManager::getInstance()->removeTask(pTask->objectName());
                break;
            }

        }
    }

    TaskItem *pTaskPre = TaskManager::getInstance()->addTask("sPaceScan");
    TaskItem *pTask = TaskManager::getInstance()->addTask("sPaceScan");
    CommandItem* pCommandItemPre = NULL;
    CommandItem* pCommandItem = NULL;

    //冷空的开始结束时间，开始结束位置
    double starttime=0.0;
    double endtime=0.0;
    //double ewstart=0.0;
    double ewend=0.0;
    //double nsstart=0.0;
    double nsend=0.0;
    //自动补充冷空驻留时间
    double stableTime=0.0;

    if(TaskManager::getInstance()->curIns().contains("FY4B-Agr"))
    {
        stableTime=0.2;
    }

    QDir settingDir(QDir::currentPath());
    settingDir.cdUp();
    settingDir.setPath(settingDir.absolutePath().append("/config/FY4TaskOptimization"));
    QSettings settings(settingDir.absoluteFilePath("setting.ini"),QSettings::IniFormat);
    settings.beginGroup(TaskManager::getInstance()->curIns().append("-InstructionTime"));

    if(settings.contains("stableTime"))
        stableTime = settings.value("stableTime").toDouble();
    else
    {
        settings.setValue("stableTime",QString::number(stableTime,'f',6));
    }
    settings.endGroup();

    //在当前全员盘和中国区任务之前，加上冷空。开始位置为上一条指令的结束位置，结束位置为全员盘开始位置。
    CommandItem *preCmd=NULL;
    CommandItem * curCmd=NULL;
    QVector<CommandItem *> vctCmd = TaskManager::getInstance()->getSortCommand();
    for(int i=0; i<vctCmd.count(); ++i)
    {

        curCmd = vctCmd.at(i);
        double dCurEW_S= curCmd->getValue(ScriptItem::Pos_EWStart);
        double dCurNS_S = curCmd->getValue(ScriptItem::Pos_NSStart);

        double dCurEW_E=curCmd->getValue(ScriptItem::Pos_EWEnd);
        double dCurNS_E=curCmd->getValue(ScriptItem::Pos_NSEnd);
        //全圆盘前补冷空
        if(FulldiskpreSpace)
        {
            if(i)
            {
                preCmd=vctCmd.at(i-1);
            }

            //如果当前位置是全员盘，并且前一个任务不是冷空，就补冷空。
            if(curCmd->getName().split(" ").at(0)=="FulldiskNormal")
            {
                //如果前一个位置没有时间相同的冷空，就补冷空。否则continue
                if(i>0&&preCmd->getName().split(" ").at(0)=="sPaceScan")
                {
                    if(curCmd->getValue(ScriptItem::Time_Start)-preCmd->getValue(ScriptItem::Time_End)-(1e-12)<0)
                        continue;
                }

                pCommandItemPre=pTaskPre->addCommand("sPaceScan "+QString("%1").arg(i+1));
                QString sObj = pCommandItemPre->objectName();
                sObj.replace("sPaceScan", "sPaceScanAutoPre");
                pCommandItemPre->setObjectName(sObj);
                pCommandItemPre->setWorkMode(CommandItem::Mode_FastPoint);

                QTableWidgetItem* pTableItem = new QTableWidgetItem(pTaskPre->getName());
                pTableItem->setData(Qt::WhatsThisRole,pTaskPre->objectName());

                //东西镜观测位置为当前行全圆盘起始位置。                
                //20200720修改全圆盘前冷空在距离全圆盘前1.5°，现0.48度；冷空的结束位置就是冷空位置到全圆盘的开始位置快指的时间+指令间隔时间；
               if(fulldispreangle-1E-6<0)
               {
                   ewend=dCurEW_S;
                   nsend=dCurNS_S;
                   endtime=curCmd->getValue(ScriptItem::Time_Start)-FulldiskstableTime;
               }
               else
               {
                    ewend=curCmd->getValue(ScriptItem::Pos_realEWstart)+fulldispreangle;
                    nsend=dCurNS_S;
                    endtime=curCmd->getValue(ScriptItem::Time_Start)-instructionIntervalTime*2-
                            TaskManager::getInstance()->currentInstrument()->getQuickTime(ewend,nsend,
                                dCurEW_S,dCurNS_S, TaskManager::getInstance()->currentInstrument()->mdFastPointSpeed);
               }
                //如果是全圆盘前冷空，结束位置为全圆盘开始位置-全圆盘前驻留时间。
                //如果是中国区前冷空，结束位置为中国区开始位置-指令间隔时间-冷空位置到中国区开始位置快指时间-指令间隔时间

                starttime=endtime-stableTime;
                //将冷空指令赋值。
                CommandItem::FastTargetPos pos;
                pos.miTargetPosWorkMode=pTaskPre->objectName().split(":").at(1);
                pos.mdTargetPosDuration=stableTime;
                pCommandItemPre->setFastPosMode(pos);
                pCommandItemPre->setValue(ScriptItem::Time_Start,starttime);
                pCommandItemPre->setValue(ScriptItem::Time_End,endtime);
                pCommandItemPre->setValue(ScriptItem::Pos_EWEnd,ewend);
                pCommandItemPre->setValue(ScriptItem::Pos_EWStart,ewend);
                pCommandItemPre->setValue(ScriptItem::Pos_NSStart,nsend);
                pCommandItemPre->setValue(ScriptItem::Pos_NSEnd,nsend);
            }

        }
        //0526修改中国区前冷空是否增加由配置文件决定
        //中国区前补冷空
        if(ChinascanpreSpace)
        {
            if(i)
            {
                preCmd=vctCmd.at(i-1);
            }

            //如果当前位置是全员盘，并且前一个任务不是冷空，就补冷空。
            if(curCmd->getName().split(" ").at(0)=="ChinascanNormal")
            {
                //如果前一个位置没有时间相同的冷空，就补冷空。否则continue
                if(i>0&&preCmd->getName().split(" ").at(0)=="sPaceScan")
                {
                    if(curCmd->getValue(ScriptItem::Time_Start)-preCmd->getValue(ScriptItem::Time_End)-(1e-12)<0)
                        continue;
                }

                pCommandItemPre=pTaskPre->addCommand("sPaceScan "+QString("%1").arg(i+1));
                QString sObj = pCommandItemPre->objectName();
                sObj.replace("sPaceScan", "sPaceScanAutoPre");
                pCommandItemPre->setObjectName(sObj);
                pCommandItemPre->setWorkMode(CommandItem::Mode_FastPoint);

                QTableWidgetItem* pTableItem = new QTableWidgetItem(pTaskPre->getName());
                pTableItem->setData(Qt::WhatsThisRole,pTaskPre->objectName());


                ewend = 5.0;
                nsend = 0;
                endtime=curCmd->getValue(ScriptItem::Time_Start)-ChinaScanstableTime-instructionIntervalTime-
                        TaskManager::getInstance()->currentInstrument()->getQuickTime(ewend,nsend,
                                                                                      curCmd->getValue(ScriptItem::Pos_EWStart),curCmd->getValue(ScriptItem::Pos_NSStart),
                                                                                      TaskManager::getInstance()->currentInstrument()->mdFastPointSpeed);
                //如果是全圆盘前冷空，结束位置为全圆盘开始位置-全圆盘前驻留时间。
                //如果是中国区前冷空，结束位置为中国区开始位置-指令间隔时间-冷空位置到中国区开始位置快指时间-指令间隔时间
                starttime=endtime-stableTime;
                //将冷空指令赋值。
                CommandItem::FastTargetPos pos;
                pos.miTargetPosWorkMode=pTaskPre->objectName().split(":").at(1);
                pos.mdTargetPosDuration=stableTime;
                pCommandItemPre->setFastPosMode(pos);
                pCommandItemPre->setValue(ScriptItem::Time_Start,starttime);
                pCommandItemPre->setValue(ScriptItem::Time_End,endtime);
                pCommandItemPre->setValue(ScriptItem::Pos_EWEnd,ewend);
                pCommandItemPre->setValue(ScriptItem::Pos_EWStart,ewend);
                pCommandItemPre->setValue(ScriptItem::Pos_NSStart,nsend);
                pCommandItemPre->setValue(ScriptItem::Pos_NSEnd,nsend);
            }

        }



#if 0
        //全圆盘后补冷空
        //如果当前位置是全员盘，就补冷空。(之前已经把所有自动规划的冷空删除，所以一定不会有自动规划冷空)
        if(curCmd->getName().split(" ").at(0)=="FulldiskNormal"/*||curCmd->getName().split(" ").at(0)=="ChinascanNormal"*/)
        {
            pCommandItem=pTask->addCommand("sPaceScan "+QString("%1").arg(i+1));
            QString sObj = pCommandItem->objectName();
            sObj.replace("sPaceScan", "sPaceScanAuto");
            pCommandItem->setObjectName(sObj);
            pCommandItem->setWorkMode(CommandItem::Mode_FastPoint);

            QTableWidgetItem* pTableItem = new QTableWidgetItem(pTask->getName());
            pTableItem->setData(Qt::WhatsThisRole,pTask->objectName());
            //东西镜观测位置为当前行全圆盘起始位置。
            ewend=dCurEW_S;
            nsend=dCurNS_S;
            //开始时间为全圆盘结束位置，+全圆盘后指令间隔时间，+结束位置到开始位置的快速指向时间
            starttime=curCmd->getValue(ScriptItem::Time_End)+instructionIntervalTime+TaskManager::getInstance()->currentInstrument()
                    ->getQuickTime(dCurEW_E,dCurNS_E,dCurEW_S,dCurNS_S,mdFastPointSpeed);
            endtime=starttime+stableTime;

            //将冷空指令赋值。
            CommandItem::FastTargetPos pos;
            pos.miTargetPosWorkMode=pTask->objectName().split(":").at(1);
            pos.mdTargetPosDuration=stableTime;
            pCommandItem->setFastPosMode(pos);
            pCommandItem->setValue(ScriptItem::Time_Start,starttime);
            pCommandItem->setValue(ScriptItem::Time_End,endtime);
            pCommandItem->setValue(ScriptItem::Pos_EWEnd,ewend);
            pCommandItem->setValue(ScriptItem::Pos_EWStart,ewend);
            pCommandItem->setValue(ScriptItem::Pos_NSStart,nsend);
            pCommandItem->setValue(ScriptItem::Pos_NSEnd,nsend);
        }
#else
        //    if(TaskManager::getInstance()->curIns().contains("FY4B-Agr")&&curCmd->getName().split(" ").at(0)=="ChinascanNormal")
        //    {
        //        //中国区前补冷空
        //        pCommandItem=pTask->addCommand("sPaceScan "+QString("%1").arg(i+1));
        //        QString sObj = pCommandItem->objectName();
        //        sObj.replace("sPaceScan", "sPaceScanAuto");
        //        pCommandItem->setObjectName(sObj);
        //        pCommandItem->setWorkMode(CommandItem::Mode_FastPoint);

        //        QTableWidgetItem* pTableItem = new QTableWidgetItem(pTask->getName());
        //        pTableItem->setData(Qt::WhatsThisRole,pTask->objectName());
        //        //东西镜观测位置为当前行全圆盘起始位置。----此处需要改为开始位置为全员盘开始x和开始y。
        //       // ewend=dCurEW_S;
        //       // nsend=dCurNS_S;
        //        //开始时间为中国区开始位置，-指令间隔时间-冷空开始位置到中国区开始位置快指时间，-指令间隔时间，-冷空时间
        //        //starttime=curCmd->getValue(ScriptItem::Time_End)+instructionIntervalTime+TaskManager::getInstance()->currentInstrument()
        //          //      ->getQuickTime(dCurEW_E,dCurNS_E,dCurEW_S,dCurNS_S,mdFastPointSpeed);
        //        endtime=starttime+stableTime;

        //        //将冷空指令赋值。
        //        CommandItem::FastTargetPos pos;
        //        pos.miTargetPosWorkMode=pTask->objectName().split(":").at(1);
        //        pos.mdTargetPosDuration=stableTime;
        //        pCommandItem->setFastPosMode(pos);
        //        pCommandItem->setValue(ScriptItem::Time_Start,starttime);
        //        pCommandItem->setValue(ScriptItem::Time_End,endtime);
        //        pCommandItem->setValue(ScriptItem::Pos_EWEnd,ewend);
        //        pCommandItem->setValue(ScriptItem::Pos_EWStart,ewend);
        //        pCommandItem->setValue(ScriptItem::Pos_NSStart,nsend);
        //        pCommandItem->setValue(ScriptItem::Pos_NSEnd,nsend);
        //    }
#endif

    }

    TaskManager::getInstance()->slot_updateTask(QString(),QString(),QString());

    return true;
}

void ScriptItemTree::removeTask(const QString &sTaskObj)
{
    //遍历子节点，到对应的父节点objname，删除
    TaskItem *pTask=TaskManager::getInstance()->getTask(sTaskObj);
    if(NULL==pTask)
        return ;
    QVector<CommandItem *>vctCommands=pTask->allCommands();
    foreach(CommandItem *pCommand,vctCommands)
    {
        for(int i=0;i<this->topLevelItemCount();++i)
        {
            if(this->topLevelItem(i)->data(0,Qt::WhatsThisRole).toString()==pCommand->objectName())
            {
                QTreeWidgetItem *pTopItem=this->takeTopLevelItem(i);
                delete pTopItem;
                pTopItem=NULL;
                break;
            }
        }
    }
}

/**
 * @brief ScriptItemTree::slot_autoPlan 自动规划，补齐快速指向
 */
void ScriptItemTree::slot_autoPlan()
{
    //如果是02星
    //if(TaskManager::getInstance()->curIns().contains("FY4B-Agr"))
    autoPlansPaceScan();

    QVector<CommandItem *> vctCmd = TaskManager::getInstance()->getSortCommand();

    //将自动补齐指令删除，重新补充
    for(int i=0;i<vctCmd.size();++i)
    {
        if(vctCmd.at(i)->getName().contains("FastPointing"))
        {
            QString taskname=vctCmd.at(i)->task->objectName();
            TaskManager::getInstance()->removeTask(taskname);
            break;
        }
    }

    TaskItem *pTask = TaskManager::getInstance()->addTask("FastPointing");

    QTableWidgetItem* pTableItem = new QTableWidgetItem(pTask->getName());
    pTableItem->setData(Qt::WhatsThisRole,pTask->objectName());

    CommandItem* pCommandItem = NULL;

    //快速指向的开始结束时间，开始结束位置
    double starttime=0.0;
    double endtime=0.0;
    double ewstart=0.0;
    double ewend=0.0;
    double nsstart=0.0;
    double nsend=0.0;


    //指令的结束时间是第一个指令的开始时间。如果mode是区域扫描实际的结束时间是计算出来的快指的时间+0.2；如果是mode是fastpoint结束时间就是实际结束时间。
    CommandItem *precmd=NULL;
    CommandItem * curCmd=NULL;
    vctCmd = TaskManager::getInstance()->getSortCommand();
    for(int i=0; i<vctCmd.count(); ++i)
    {

        curCmd = vctCmd.at(i);

        if(i)
        {

            //1104如果前一个指令是内黑体，结束时间就要是i-2  黑体任务第一个，前一个是内黑体，需要处理
            precmd=vctCmd.at(i-1);
        }
        if(i>=2)
        {
            if((precmd->getName().split(" ").at(0)=="BlackbodyScan")&&(precmd->getValue(ScriptItem::Time_End)-1e-6<precmd->getValue(ScriptItem::Time_Start)))
            {
                precmd=vctCmd.at(i-2);
            }
        }


        //当前指令不是快指，并且前一个指令不是快指，就补快指。vctCmd.at(i-1)->getName()=="FastPoint"..中国区和全员盘前已经有冷空，不需要补快指.
        if(curCmd->getName().mid(0,9)=="FastPoint"/*||curCmd->getName().split(" ").at(0)=="FulldiskNormal"||curCmd->getName().split(" ").at(0)=="ChinascanNormal"*/)
            continue;
        if(i>0&&precmd->getName().mid(0,9)=="FastPoint")
            continue;

        //1104如果当前指令是内黑体观测，开始时间结束时间是一样的，不补快指，前一个指令会不会是内黑体？
       if(curCmd->getName().split(" ").at(0)=="BlackbodyScan"&&(curCmd->getValue(ScriptItem::Time_End)-1e-6)<curCmd->getValue(ScriptItem::Time_Start))
           continue;


        //0502新加，用于全圆盘前补冷空
        if(curCmd->getName().split(" ").at(0)=="FulldiskNormal")
        {
            if(FulldiskpreSpace&&fulldispreangle-1E-6<0)
                continue;
        }
//        //0502新加，用于中国区前补冷空
//        if(curCmd->getName().split(" ").at(0)=="ChinascanNormal")
//        {
//            if(ChinascanpreSpace)
//                continue;
//        }
        pCommandItem=pTask->addCommand("FastPointing "+QString("%1").arg(i+1));
        pCommandItem->setWorkMode(CommandItem::Mode_FastPoint);


        //以下if针对于未改位置之前的load
        if(curCmd->getWorkMode()==CommandItem::Mode_FastPoint&&
                (curCmd->getValue(ScriptItem::Pos_EWStart)!=curCmd->getValue(ScriptItem::Pos_EWEnd)||
                 curCmd->getValue(ScriptItem::Pos_NSStart)!=curCmd->getValue(ScriptItem::Pos_NSEnd)))
        {
            curCmd->setValue(ScriptItem::Pos_EWStart,curCmd->getValue(ScriptItem::Pos_EWEnd));
            curCmd->setValue(ScriptItem::Pos_NSStart,curCmd->getValue(ScriptItem::Pos_NSEnd));
        }


        double dpreEW_S= curCmd->getValue(ScriptItem::Pos_EWStart);
        double dpreNS_S= curCmd->getValue(ScriptItem::Pos_NSStart);

        //除去第一个指令开始位置为星下点。，没有上一个指令的结束位置。
        if(i)
        {
            //1104，如果第一条指令是内黑体，第二条指令是黑体，就会有问题，所做修改
            if(!((precmd->getName().split(" ").at(0)=="BlackbodyScan")&&(precmd->getValue(ScriptItem::Time_End)-1e-6<precmd->getValue(ScriptItem::Time_Start))))
            {
                ewstart=precmd->getValue(ScriptItem::Pos_EWEnd);
                nsstart=precmd->getValue(ScriptItem::Pos_NSEnd);
            }
        }
        ewend=dpreEW_S;
        nsend=dpreNS_S;
        double quicktime=TaskManager::getInstance()->currentInstrument()->getQuickTime(ewstart,nsstart,ewend,nsend,TaskManager::getInstance()->currentInstrument()->mdFastPointSpeed);

        //如果当前工作模式是区域扫描
        if(curCmd->getWorkMode()==CommandItem::Mode_SlideScan)
        {
            if(curCmd->getName().contains("FulldiskNormal"))
            {
                endtime=curCmd->getValue(ScriptItem::Time_Start)-FulldiskstableTime;
            }
            else if(curCmd->getName().contains("ChinascanNormal"))
            {
                endtime=curCmd->getValue(ScriptItem::Time_Start)-ChinaScanstableTime;
            }
            else if(curCmd->getName().contains("MidRegionScan"))
            {
                endtime=curCmd->getValue(ScriptItem::Time_Start)-MidReginstableTime;
            }
        }
        else if(curCmd->getWorkMode()==CommandItem::Mode_StepScan)
        {
            //------------留给步进成像的时间计算.
        }
        else
        {
           endtime=curCmd->getValue(ScriptItem::Time_Start);
         }
        starttime=endtime-quicktime;

        //将快速指向的时间和位置赋值。
        pCommandItem->setValue(ScriptItem::Time_Start,starttime);
        pCommandItem->setValue(ScriptItem::Time_End,endtime);
        pCommandItem->setValue(ScriptItem::Pos_EWEnd,ewend);
        pCommandItem->setValue(ScriptItem::Pos_EWStart,ewstart);
        pCommandItem->setValue(ScriptItem::Pos_NSStart,nsstart);
        pCommandItem->setValue(ScriptItem::Pos_NSEnd,nsend);
    }
    TaskManager::getInstance()->slot_updateTask(QString(),QString(),QString());
    scriptCheck();
}
//指令冲突检查
//遍历指令时间，如果第二个以后的快速指向的前一个指令结束时间间隔小于指令间隔时间0.1s，就报错。
void ScriptItemTree::scriptCheck()
{
    QStringList  errorMsgVector;
    QVector<CommandItem *> vctCmd = TaskManager::getInstance()->getSortCommand();

    //快速指向和快指前一个指令
    CommandItem* quickpointItem=NULL;
    CommandItem* preitem=NULL;
    double temp=0.0;
    for(int i=1; i<=vctCmd.count()-1; ++i)
    {
        if(vctCmd.at(i)->getName().mid(0,9)=="FastPoint")
        {
            quickpointItem=vctCmd.at(i);
            preitem=vctCmd.at(i-1);
            temp=quickpointItem->getValue(ScriptItem::Time_Start)-preitem->getValue(ScriptItem::Time_End);
            if(temp-instructionIntervalTime+1e-12<0)
            {
                errorMsgVector.append(preitem->objectName());
                errorMsgVector.append(quickpointItem->objectName());
            }
        }
    }

    for(int i=0; i<this->topLevelItemCount(); ++i)
    {
        QString sTreeItemDat = this->topLevelItem(i)->data(0,Qt::WhatsThisRole).toString();
        if(errorMsgVector.contains(sTreeItemDat))
        {
            this->topLevelItem(i)->setData(0,Qt::BackgroundColorRole,QColor(255,0,0,255));
        }
        else
        {
            this->topLevelItem(i)->setData(0,Qt::BackgroundColorRole,QColor(255,0,0,0));
        }
    }
}

void ScriptItemTree::slot_editStyle()
{
    TaskStyleEditor dlg;
    dlg.exec();
}
